package com.qcby.aop;

import com.qcby.dao.OperateLogDao;
import com.qcby.entity.OperateLog;
import com.qcby.util.CurrentHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;

@Slf4j
@Aspect
@Component
public class OperateLogAspect {

    @Autowired
    private OperateLogDao operateLogMapper;

    // 定义切点：拦截com.itheima.controller包下的所有方法
    @Around("@annotation(com.qcby.anno.Log)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 记录开始时间
        long startTime = System.currentTimeMillis();

        // 执行目标方法，获取返回值
        Object result = joinPoint.proceed();

        // 记录结束时间
        long endTime = System.currentTimeMillis();
        long costTime = endTime - startTime;
        log.info( "方法执行耗时：{}", costTime);
        // 获取方法签名信息
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        // 创建操作日志对象
        OperateLog operateLog = new OperateLog();

        // 设置类名和方法名
        operateLog.setClassName(joinPoint.getTarget().getClass().getName());
        operateLog.setMethodName(signature.getName());

        // 设置方法参数
        Object[] args = joinPoint.getArgs();
        operateLog.setMethodParams(Arrays.toString(args));
        log.info( "方法参数：{}", operateLog.getMethodParams());
        log.info( "返回值：{}", operateLog.getReturnValue());
        log.info("类名：{}", operateLog.getClassName());
        // 设置返回值
        operateLog.setReturnValue(result != null ? result.toString() : "null");

        // 设置操作时间
        operateLog.setOperateTime(LocalDateTime.now());

        // 设置执行耗时
        operateLog.setCostTime(costTime);

        // 获取操作人ID（这里假设从请求头中获取，实际根据你的认证系统调整）
        Integer empId = CurrentHolder.getCurrentId();
        operateLog.setOperateEmpId(empId);

        // 保存操作日志
        operateLogMapper.insert(operateLog);

        return result;
    }
}